#ifndef LIVETRACK_H
#define LIVETRACK_H

#include <QObject>
#include <QGeoCoordinate>
QTM_USE_NAMESPACE

#include "gps_track.h"
#include "configuration.h"
#include "livetrackautosaver.h"
#include "controls/rotatingwidget.h"
#include "workers/workerautoload.h"
#include "workers/workerautosave.h"

class FTTabWidget;
class FTPushButton;
class FTPushButtonIcon;
class FTLabel;
class FTList;
class FTCheckBox;
class FTLatLonEdit;
class FTLineEdit;
class StatsTracks;
class FTTextArea;

class LiveTrack : public RotatingWidget
{
    Q_OBJECT
public:

    friend class WorkerAutoLoad;
    friend class WorkerAutoSave;

    explicit LiveTrack();
    ~LiveTrack();

    // Get the real track
    GPS_track* track() const;

    // Get last point (if any)
    const GPS_point* lastPoint() const;
    // Is tracking currently active?
    bool trackingActive() const;

    // Some quickie to add stuff to LiveTrack without accessing directly the track
    void createWaypoint(double lat, double lon, int alt);



signals:
    // Emit when tracking goes from inactive to active or viceversa
    void trackingStatusChanged(bool);
    // Emit when track length changes
    void trackChanged(int, int);
    // Popup the livetrack dialog
    void livetrackPopup();
    // Send new destination waypoint
    void setDestination(QGeoCoordinate qg = QGeoCoordinate() );

public slots:
    // start/stop tracking
    void startTracking(bool);
    // toggle tracking
    void toggleTracking();
    // save&quit
    void prepareToQuit();
    // Receive a new point (might not be added, tough)
    void addPointFromGps(GPS_point);
    // update tracking mode
    void trackingModeChanged( Configuration::tracking_mode, int );
    // Update minimuum dop
    void updateMinimumDOP(int);

private: // Tracking mode

    // Store tracking mode for quick access
    Configuration::tracking_mode track_mode;
    int track_value;

    bool checkAutomatic(const GPS_point&, const GPS_point*);
    bool checkTimeMode(const GPS_point&, const GPS_point*);
    bool checkDistanceMode(const GPS_point&, qreal distance);

    // this is required to prevent races when receiving new points during save/load operations
    void trackingLock(bool);

private: // Internal data and states

    // Keep track of the currently active leg
    int _activeLeg;
    // is tracking active?
    bool _trackingActive;
    // Filename management!
    void setFilename(const QString&);
    QString _filename;
    // The actual track!
    GPS_track* _track;

private: // Autosave management

    void updateFilename(const QString&);
    LiveTrackAutosaver autosaver;

private: // Dialog methods and attributes

    // Build dialogs
    void buildDialogMain();
    void buildDialogLegs();
    void buildDialogWaypoints();
    void builddialogStats();
    // Main tabber widget
    FTTabWidget* livetrackTab;

    int minimumDop;

private: // Main page

    QWidget* mainPage;

    // Set title
    FTLabel* titleLabel;
    FTLineEdit* titleEdit;
    // Set description:
    FTLabel* descLabel;
    QLineEdit* descEdit;
    FTPushButton* startButton;

    // Filename management
    FTLabel* filenameLabel;
    FTPushButtonIcon* filenamesaveButton;
    FTPushButtonIcon* filenameloadButton;

    // Simple info label
    FTTextArea* infoLabel;

    // Reset livetrack contents
    FTPushButtonIcon* resetButton;

private slots:

    // Request a new filename to save the track
    void saveTrackAs();
    // Save a track (internally revert to SaveAs if filename is missing)
    void saveTrack();

    // Check if track is modified, ask for save, then load track
    void loadTrack();
    // Reset to empty track
    void resetTrack();
    // Slots for the livetrack info data edit
    void titleUpdated(QString);
    void descUpdated(QString);
    // Update info label with track data
    void updateInfoLabel();

    // intercept tab change and update stats
    void pageChanged();

private: // Stats page
    StatsTracks* stats;

private: // Legs page

    QWidget* legsPage;

    // Rebuild contents of list of legs
    void populateListLegs();
    void openLegEdit();
    void closeLegEdit();
    bool isNewLeg;

    // Top widgets
    FTPushButton* newlegButton;
    FTList* legsList;

    // Edit widgets
    QWidget* editlegPane;
    FTLabel* legnameLabel;
    QLineEdit* legnameEdit;
    FTPushButton* legcolorButton;
    FTPushButton* savelegButton;
    FTPushButton* ignorelegButton;

    FTCheckBox* activelegButton;
    FTPushButtonIcon* deletelegButton;

    // Edit leg widgets
    QColor tmpLegColor;
    int selectedLegId;

private slots:

    void changeActiveLeg();
    void editLeg(int);
    void removeLeg();

    // Slots for the leg edit buttons
    void confirmLeg();
    void ignoreLeg();
    void setColorLeg();
    void createNewLeg();

private: // waypoints page

    void populateListWaypoints();
    void openWaypointEdit();
    void closeWaypointEdit();
    bool isNewWaypoint;

    QWidget* waypointsPage;

    FTList* waypointsList;
    QColor tmpWaypointColor;
    int selectedWaypointId;

    // Edit widgets
    FTLatLonEdit* waypointlatlonEdit;
    QWidget* editwaypointPane;
    FTLabel* waypointnameLabel;
    QLineEdit* waypointnameEdit;
    FTLabel* waypointdescLabel;
    QLineEdit* waypointdescEdit;
    FTLabel* waypointeleLabel;
    QLineEdit* waypointeleEdit;
    FTPushButton* waypointcolorButton;
    FTPushButton* savewaypointButton;
    FTPushButton* ignorewaypointButton;
    FTPushButtonIcon* deletewaypointButton;
    FTPushButton* gotoButton;

private slots:

    void editWaypoint(int);
    void removeWaypoint();

    // Slots for the leg edit buttons
    void confirmWaypoint();
    void ignoreWaypoint();
    void setColorWaypoint();
    void createNewWaypoint();
    void gotoWaypoint();


private:
    QLayout* createHorizontal();
    QLayout* createVertical();
};

#endif // LIVETRACK_H
